package ml;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class StrongClassifer {
	private ArrayList<WeakClassifier> m_weak_classifiers = new ArrayList<WeakClassifier>();
	private ArrayList<Integer> m_feature_indices = new ArrayList<Integer>();
	private ArrayList<Double> m_weights = new ArrayList<Double>();

	public double perform(ArrayList<Double> features) {
		assert (m_weak_classifiers.size() == m_weights.size());
		assert (m_weak_classifiers.size() == m_feature_indices.size());

		double result = 0;
		for (int i = 0; i < m_weak_classifiers.size(); ++i) {
			if (m_weak_classifiers.get(i).judge(features.get(m_feature_indices.get(i)))) {
				result += m_weights.get(i);
			} else {
				result -= m_weights.get(i);
			}
		}

		return result;
	}

	public boolean judge(ArrayList<Double> features) {
		return perform(features) > 0;
	}

	public void addWeakClassifer(WeakClassifier weakClassifer, int index, double weight) {
		m_weak_classifiers.add(weakClassifer);
		m_feature_indices.add(index);
		m_weights.add(weight);
	}

	public void dump(String file_name) {
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter(file_name));
			for (int i = 0; i < m_weak_classifiers.size(); ++i) {
				bw.write(m_weak_classifiers.get(i).toString());
				bw.write("\t");
				bw.write(Integer.toString(m_feature_indices.get(i)));
				bw.write("\t");
				bw.write(Double.toString(m_weights.get(i)));
				bw.write("\r\n");
			}
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void load(String file_name) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(file_name));
		m_weak_classifiers.clear();
		m_feature_indices.clear();
		m_weights.clear();

		StringTokenizer token = null;
		while (br.ready()) {
			token = new StringTokenizer(br.readLine());
			WeakClassifier weak_classifier = new WeakClassifier();
			weak_classifier.m_threshold = Double.valueOf(token.nextToken());
			weak_classifier.m_less_is_pos = Boolean.valueOf(token.nextToken());
			m_weak_classifiers.add(weak_classifier);

			m_feature_indices.add(Integer.valueOf(token.nextToken()));
			m_weights.add(Double.valueOf(token.nextToken()));
		}

		br.close();
	}
}
